package com.google.code.customercare.model.ext;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;

public class HibernateUtil {
	private static final SessionFactory sessionFactory;
	@SuppressWarnings("rawtypes")
	private static final ThreadLocal threadSession = new ThreadLocal();
	@SuppressWarnings("rawtypes")
	private static final ThreadLocal threadTransaction = new ThreadLocal();
	
	static{
		Configuration configuration = new Configuration();	
		configuration.configure();
		ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();   
		sessionFactory = (SessionFactory) configuration.buildSessionFactory(serviceRegistry);
	}
	
	@SuppressWarnings("unchecked")
	public static Session getSession() throws Exception {
		Session s = (Session) threadSession.get();
		try{
			if(s == null || !s.isOpen()) {
				s = sessionFactory.getCurrentSession();
				threadSession.set(s);
			}
		}catch(Exception e){
			throw new Exception(e);
		}
		return s;
	}
	
	@SuppressWarnings("unchecked")
	public static void closeSession() throws Exception {
		try{
			Session s = (Session) threadSession.get();
			if(s != null && s.isOpen()) {
				s.close();
			}
			threadSession.set(null);
		}catch(Exception e){
			throw new Exception(e);
		}
	}
	
	@SuppressWarnings("unchecked")
	public static void beginTransaction() throws Exception {
		Transaction tx = (Transaction) threadTransaction.get();
		try{
			if(tx == null) {
				tx = getSession().beginTransaction();
				threadTransaction.set(tx);
			}
		}catch(Exception e){
			throw new Exception(e);
		}
	}
	
	@SuppressWarnings("unchecked")
	public static void commitTransaction() throws Exception {
		Transaction tx = (Transaction) threadTransaction.get();
		try{
			if(tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {
				tx.commit();
			}
			threadTransaction.set(null);
		}catch(Exception e){
			throw new Exception(e);
		}
	}
	
	@SuppressWarnings("unchecked")
	public static void rollbackTransaction() throws Exception {
		Transaction tx = (Transaction) threadTransaction.get();
		try{
			if(tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			threadTransaction.set(null);
		}catch(Exception e){
			throw new Exception(e);
		}finally{
			closeSession();
		}
	}
}
